#include "KCPServer.h"
#include <WinSock2.h>

KCPServer::KCPServer()
{
	tcpServer = new TCPServer();
	tcpServer->RegisterClientConnectedCallback(&KCPServer::OnTCPClientConnected, this);
	tcpServer->RegisterClientDisconnectedCallback(&KCPServer::OnTCPClientDisconnected, this);
	tcpServer->RegisterClientReceivedCallback(&KCPServer::OnTCPClientReceived, this);
}

KCPServer::~KCPServer()
{
	Terminate();
	delete tcpServer;
}

bool KCPServer::Initialize(int port)
{
	Terminate();
	return tcpServer->Initialize(port);
}

void KCPServer::Terminate()
{
	tcpServer->Terminate();
}

void KCPServer::Update()
{
	tcpServer->Update();
	for (KCPClient* c : kcpClients)
		c->Update();
}

void KCPServer::OnClientConnected(KCPClient* client)
{
	kcpClients.insert(client);
	if (onClientConnectedEvent)
		onClientConnectedEvent(client);
}

void KCPServer::OnClientReceived(KCPClient* client, char* buffer, int len)
{
	if (onClientReceivedEvent)
		onClientReceivedEvent(client, buffer, len);
}

void KCPServer::OnTCPClientConnected(TCPClient* client)
{
	KCPClient* kcpClient = new KCPClient();
	if (!kcpClient->SetServerClient(client))
	{
		client->Disconnect();
		return;
	}
	client->user = kcpClient;
	kcpClient->user = this;
	tcpClients.insert(client);
}

void KCPServer::OnTCPClientDisconnected(TCPClient* client)
{
	KCPClient* kcp = reinterpret_cast<KCPClient*>(client->user);
	if (onClientDisconnectedEvent)
		onClientDisconnectedEvent(kcp);
	kcpClients.erase(kcp);
	delete kcp;
	tcpClients.erase(client);
}

void KCPServer::OnTCPClientReceived(TCPClient* client, char* buffer, int len)
{
	KCPClient* kcp = reinterpret_cast<KCPClient*>(client->user);
	sockaddr_in addr;
	client->GetRemoteAddr(&addr);
	kcp->SetRemoteAddr(&addr);
	kcp->OnTCPReceived(buffer, len);
}
